package com.win.oauth.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fyl.controller.BaseController;
import com.fyl.core.advance.constant.enums.CommonResponseEnum;
import com.fyl.core.response.RS;
import com.fyl.utils.BaseTreeUtil;
import com.win.oauth.dto.*;
import com.win.oauth.entity.Role;
import com.win.oauth.entity.RolePermissionRel;
import com.win.oauth.entity.UserRoleRel;
import com.win.oauth.service.IPermissionService;
import com.win.oauth.service.IRolePermissionRelService;
import com.win.oauth.service.IRoleService;
import com.win.oauth.service.IUserRoleRelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author youlian.fei
 * @since 2020-03-14
 */
@RestController
@RequestMapping("/oauth/role")
public class RoleController extends BaseController<IRoleService, Role> {

    @Autowired
    IPermissionService permissionService;

    @Autowired
    IRolePermissionRelService rolePermissionRelService;

    @Autowired
    IUserRoleRelService userRoleRelService;

    @PostMapping({"/add"})
    public RS<Void> add(@RequestBody Role entity) {
        return this.baseService.save(entity) ? RS.genSuccess() : RS.genFail(CommonResponseEnum.FAIL);
    }

    @PostMapping({"/update"})
    public RS<Void> update(@RequestBody Role entity) {
        return this.baseService.updateById(entity) ? RS.genSuccess() : RS.genFail(CommonResponseEnum.FAIL);
    }

    @PostMapping({"/delete"})
    public RS<Void> delete(@RequestBody Collection<Long> idList) {
        Integer count = userRoleRelService.lambdaQuery().in(UserRoleRel::getRoleId, idList).count();
        if (count > 0) {
            return RS.genFail("角色被用户绑定");
        }
        rolePermissionRelService.remove(new LambdaQueryWrapper<RolePermissionRel>().in(RolePermissionRel::getRoleId, idList));
        return this.baseService.removeByIds(idList) ? RS.genSuccess() : RS.genFail(CommonResponseEnum.FAIL);
    }


    @GetMapping("/getPermissionTree")
    public RS<List<AntdTreeDTO>> getPermissionTree() {
        List<PermModuleFunDTO> permModuleFuns = permissionService.listPermModuleFun();
        List<AntdTreeDTO> resp = BaseTreeUtil.build(el -> {
            AntdTreeDTO dto = new AntdTreeDTO();
            dto.setId(Optional.ofNullable(el.getModuleId()).orElse(0L));
            dto.setParentId(Optional.ofNullable(el.getModuleParentId()).orElse(el.getFunModuleId()));
            dto.setKey(el.getPermId());
            dto.setTitle(Optional.ofNullable(el.getModuleName()).orElse(el.getFunName()));
            return dto;
        }, permModuleFuns);
        return RS.genSuccess(resp);
    }

    @GetMapping("/getPermissions")
    public RS<List<PermModuleDTO>> getPermissions() {
        List<PermModuleDTO> permModules = permissionService.listPermModule();
        List<PermFunDTO> permFuns = permissionService.listPermFun();
        for (PermModuleDTO pm : permModules) {
            List<PermFunDTO> funs = new ArrayList<>();
            for (PermFunDTO pf : permFuns) {
                if (pf.getFunModuleId().equals(pm.getModuleId())) {
                    funs.add(pf);
                }
            }
            pm.setFuns(funs);
        }
        return RS.genSuccess(permModules);
    }

    @GetMapping("/getPermsByRoleId")
    public RS<List<Long>> getPermsByRoleId(@RequestParam Long roleId) {
        List<RolePermissionRel> list = rolePermissionRelService.lambdaQuery().eq(RolePermissionRel::getRoleId, roleId).list();
        List<Long> resp = list.stream().map(RolePermissionRel::getPermissionId).collect(Collectors.toList());
        return RS.genSuccess(resp);
    }


    @PostMapping("/updatePerms")
    public RS<Void> updatePerms(@RequestBody RolePermsDTO rolePermsDTO) {
        Long roleId = rolePermsDTO.getRoleId();
        List<Long> permIds = rolePermsDTO.getPermIds();

        rolePermissionRelService.remove(
                new LambdaQueryWrapper<RolePermissionRel>().eq(RolePermissionRel::getRoleId, roleId));

        List<RolePermissionRel> toSave = permIds.stream().map(permId -> {
            RolePermissionRel rel = new RolePermissionRel();
            rel.setRoleId(roleId);
            rel.setPermissionId(permId);
            return rel;
        }).collect(Collectors.toList());

        rolePermissionRelService.saveBatch(toSave);
        return RS.genSuccess();
    }

}
